package com.ffcs.crmd.tsp.server.jdbc.service.impl;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import com.ffcs.crmd.tsp.common.exception.TspException;
import com.ffcs.crmd.tsp.server.jdbc.entity.JobDetail;
import com.ffcs.crmd.tsp.server.jdbc.entity.JobDetailParam;
import com.ffcs.crmd.tsp.server.jdbc.repository.JobDetailRepository;
import com.ffcs.crmd.tsp.server.jdbc.service.IJobDetailParamService;
import com.ffcs.crmd.tsp.server.jdbc.service.IJobDetailService;

/**
 * 
 * 功能说明:子任务服务
 *
 * @author ZHONGFUHUA
 * 
 * @since 1.0.0-SNAPSHOT
 *
 */
public class JobDetailServiceImpl implements IJobDetailService {
    
    private IJobDetailParamService jobDetailParamService;
    
    private JobDetailRepository    jobDetailRepository = new JobDetailRepository();
    
    public JobDetailServiceImpl() {
    }
    
    @Override
    public JobDetail get(Connection conn, JobDetail jobDetail) throws TspException {
        List<Object> params = new ArrayList<Object>();
        params.add(jobDetail.getId());
        params.add(jobDetail.getClusterName());
        params.add(jobDetail.getName());
        return jobDetailRepository.query(GET_JOB_DETAIL, params, conn);
    }
    
    @Override
    public int querySize(Connection conn, JobDetail jobDetail) throws TspException {
        List<Object> params = new ArrayList<Object>();
        String sql = rtp(SELECT_JOB_DETAIL, jobDetail, params, true);
        return jobDetailRepository.queryRows(sql, params, conn);
    }
    
    @Override
    public List<JobDetail> query(Connection conn, JobDetail jobDetail) throws TspException {
        List<Object> params = new ArrayList<Object>();
        String sql = rtp(SELECT_JOB_DETAIL, jobDetail, params, false);
        return jobDetailRepository.queryList(sql, params, conn);
    }
    
    @Override
    public List<JobDetail> queryPage(Connection conn, JobDetail jobDetail) throws TspException {
        List<Object> params = new ArrayList<Object>();
        String sql = rtpPage(SELECT_JOB_DETAIL, jobDetail, params);
        return jobDetailRepository.queryList(sql, params, conn);
    }
    
    @Override
    public Long add(Connection conn, JobDetail jobDetail) throws TspException {
        List<Object> params = new ArrayList<Object>();
        params.add(TspSeqServiceImpl.getSeq());
        params.add(jobDetail.getName());
        params.add(jobDetail.getDescription());
        params.add(jobDetail.getStartTime());
        params.add(jobDetail.getEndTime());
        params.add(jobDetail.getJobId());
        params.add(jobDetail.getRunning());
        params.add(jobDetail.getClusterName());
        jobDetailRepository.execute(INSERT_JOB_DETAIL, params, conn);
        return (Long) params.get(0);
    }
    
    @Override
    public boolean update(Connection conn, JobDetail jobDetail) throws TspException {
        List<Object> params = new ArrayList<Object>();
        params.add(jobDetail.getDescription());
        params.add(jobDetail.getStartTime());
        params.add(jobDetail.getEndTime());
        params.add(jobDetail.getRunning());
        params.add(jobDetail.getId());
        return jobDetailRepository.execute(UPDATE_JOB_DETAIL, params, conn);
    }
    
    @Override
    public boolean delete(Connection conn, JobDetail jobDetail) throws TspException {
        List<Object> params = new ArrayList<Object>();
        String sql = rtpDelete(DELETE_JOB_DETAIL, jobDetail, params);
        
        List<JobDetail> jobDetailList = new ArrayList<JobDetail>(); 
        JobDetail qjobDetail = this.get(conn, jobDetail);
        if(qjobDetail != null){
            jobDetailList.add(qjobDetail);
        }else{
            jobDetailList.addAll(this.query(conn, jobDetail));
        }
        
        for (JobDetail rjobDetail : jobDetailList) {
            JobDetailParam jobDetailParam = new JobDetailParam();
            jobDetailParam.setJobDetailId(rjobDetail.getId());
            jobDetailParamService.delete(conn, jobDetailParam);
        }
        return jobDetailRepository.execute(sql, params, conn);
    }
    
    @Override
    public boolean pause(Connection conn, JobDetail jobDetail) throws TspException {
        List<Object> params = new ArrayList<Object>();
        String sql = rtpPause(PAUSE_JOB_DETAIL, jobDetail, params);
        return jobDetailRepository.execute(sql, params, conn);
    }
    
    @Override
    public boolean resume(Connection conn, JobDetail jobDetail) throws TspException {
        List<Object> params = new ArrayList<Object>();
        String sql = rtpResume(RESUME_JOB_DETAIL, jobDetail, params);
        return jobDetailRepository.execute(sql, params, conn);
    }
    
    
    /**
     * 
     * 功能说明:
     * 
     * @param sql
     * @param jobDetail
     * @param params
     * @return
     */
    private String rtp(String sql, JobDetail jobDetail, final List<Object> params, boolean isLike) {
        if (jobDetail.getJobId() != null) {
            sql += " AND TJD." + COL_JOB_DETAIL_JOB_ID + " = ?";
            params.add(jobDetail.getJobId());
        }
        
        if (StringUtils.isNoneBlank(jobDetail.getName())) {
            if (isLike) {
                sql += " AND TJD." + COL_NAME + " LIKE ?";
                params.add("%" + jobDetail.getName() + "%");
            } else {
                sql += " AND TJD." + COL_NAME + " = ?";
                params.add(jobDetail.getName());
            }
        }
        
        if (StringUtils.isNoneBlank(jobDetail.getClusterName())) {
            sql += " AND TJD." + COL_CLUSTER_NAME + " = ?";
            params.add(jobDetail.getClusterName());
        }
        return sql;
    }
    
    /**
     * 
     * 功能说明:
     * 
     * @param sql
     * @param jobDetail
     * @param params
     * @return
     * @throws TspException 
     */
    private String rtpResume(String sql, JobDetail jobDetail, final List<Object> params) throws TspException {
        return rtpDelete(sql, jobDetail, params);
    }
    
    /**
     * 
     * 功能说明:
     * 
     * @param sql
     * @param jobDetail
     * @param params
     * @return
     * @throws TspException 
     */
    private String rtpPause(String sql, JobDetail jobDetail, final List<Object> params) throws TspException {
        return rtpDelete(sql, jobDetail, params);
    }
    
    
    /**
     * 
     * 功能说明:
     * 
     * @param sql
     * @param jobDetail
     * @param params
     * @return
     * @throws TspException 
     */
    private String rtpDelete(String sql, JobDetail jobDetail, final List<Object> params) throws TspException {
        if (jobDetail.getJobId() == null && jobDetail.getId() == null
            && (StringUtils.isBlank(jobDetail.getClusterName()) || StringUtils.isBlank(jobDetail.getName()))) {
            throw new TspException("['id' or 'jobId' or 'clusterName、name'] can't be null at the same time！");
        }
        
        if (jobDetail.getId() != null) {
            sql += " AND " + COL_ID + " = ?";
            params.add(jobDetail.getId());
        }
        
        if (jobDetail.getJobId() != null) {
            sql += " AND " + COL_JOB_DETAIL_JOB_ID + " = ?";
            params.add(jobDetail.getJobId());
        }
        
        if (StringUtils.isNoneBlank(jobDetail.getName()) && StringUtils.isNoneBlank(jobDetail.getClusterName())) {
            sql += " AND " + COL_NAME + " = ?";
            params.add(jobDetail.getName());
            sql += " AND " + COL_CLUSTER_NAME + " = ?";
            params.add(jobDetail.getClusterName());
        }
        return sql;
    }
    
    /**
     * 
     * 功能说明:
     * 
     * @param sql
     * @param jobDetail
     * @param params
     * @return
     */
    private String rtpPage(String sql, JobDetail jobDetail, final List<Object> params) {
        String rsql = rtp(sql, jobDetail, params, true);
        rsql += " LIMIT ?,?";
        params.add(jobDetail.getPageNumber());
        params.add(jobDetail.getPageSize());
        return rsql;
    }
    
    /**
     * 功能说明: 设置jobDetailParamService
     *
     * @param jobDetailParamService jobDetailParamService 
     */
    @Override
    public void setJobDetailParamService(IJobDetailParamService jobDetailParamService) {
        this.jobDetailParamService = jobDetailParamService;
    }
    
}
